package com.zhou.base.adapter

import android.content.Context
import android.text.TextUtils
import android.view.View
import android.view.View.OnLongClickListener
import android.view.ViewGroup
import android.view.ViewStub
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.zhou.toolsdk.R

/**
 *
 * @fuction recycleview 加载更多用的adpter
 * @date 2018/9/15
 * @author zhou
 */
abstract class RVLoadMoreAdapter<T>(
    protected var mContext: Context,
    private val recyclerView: RecyclerView,
    private val res_item_id: Int,
    var dataSet: MutableList<T>
) : RecyclerView.Adapter<RViewHolder>() {

    val TAG = RVLoadMoreAdapter::class.java.simpleName
    var isLoading = false
    private var canLoadMore = false
    private var loadMoreComplete = true
    private var loadingMore: OnLoadingMore? = null

    protected var mOnItemClickListener: OnItemClickListener? = null
    private var lastPositions: IntArray? = null
    private var footViewholder: RViewHolder? = null
    private var headerView: View? = null

    fun findMax(lastPositions: IntArray): Int {
        var max = lastPositions[0]
        for (value in lastPositions) {
            if (value > max) {
                max = value
            }
        }
        return max
    }

    fun loadMore() {
        loadingMore?.also {
            loadMoreComplete = true
            Loading(true)
            it.onLoadMore()
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RViewHolder {
        val holder: RViewHolder
        if (viewType == TYPE_HEAD) {
            holder = RViewHolder.createViewHolder(mContext, headerView!!)
        } else if (viewType == TYPE_LOAD_MORE) {
            if (footViewholder == null) {
                footViewholder = RViewHolder.createViewHolder(mContext, parent, R.layout.loadmore_default_footer)
            }
            holder = footViewholder!!
            showNormal()
        } else {
            holder = RViewHolder.createViewHolder(mContext, parent, res_item_id)
        }
        onViewHolderCreated(holder, holder.convertView, viewType)
        setListener(parent, holder, viewType)
        return holder
    }

    open fun onViewHolderCreated(
        holder: RViewHolder,
        itemView: View,
        viewType: Int
    ) {
    }

    override fun onBindViewHolder(holder: RViewHolder, position: Int) {
        if (getItemViewType(position) == TYPE_LOAD_MORE) {
            return
        }
        if (getItemViewType(position) == TYPE_HEAD) {
            return
        }
        val p = if (headerView != null) position - 1 else position
        val t = dataSet[p]
        convert(holder, t, p)
    }

    protected abstract fun convert(holder: RViewHolder, t: T, position: Int)
    override fun getItemCount(): Int {
        var size = dataSet.size
        if (headerView != null) {
            size++
        }
        if (canLoadMore) {
            size++
        }
        return size
    }

    override fun getItemViewType(position: Int): Int {
        if (position == 0) {
            if (headerView != null) {
                return TYPE_HEAD
            }
        }
        if (canLoadMore) {
            if (position == itemCount - 1) {
                return TYPE_LOAD_MORE
            }
        }
        return TYPE_NORMAL
    }

    fun setLoadingMore(loadingMore: OnLoadingMore?) {
        this.loadingMore = loadingMore
    }

    fun Loading(loading: Boolean) {
        isLoading = loading
        showNormal()
    }

    fun setLoadMoreComplete(complete: Boolean) {
        canLoadMore = loadingMore != null
        loadMoreComplete = complete
    }

    private var custom_layout_empty: LinearLayout? = null
    fun showNormal() {
        canLoadMore = loadingMore != null
        if (!canLoadMore) {
            return
        }
        if (footViewholder == null) {
            return
        }
        if (loadMoreComplete) {
            footViewholder!!.setVisible(R.id.layout_empty_default, true)
            val loadmore_default_footer_tv = footViewholder!!.getView<TextView>(R.id.loadmore_default_footer_tv)
            if (isLoading) {
                loadmore_default_footer_tv.text = "加载中"
                loadmore_default_footer_tv.setOnClickListener(null)
                footViewholder!!.setVisible(R.id.loadmore_default_footer_progressbar, true)
            } else {
                loadmore_default_footer_tv.text = "点击加载更多"
                loadmore_default_footer_tv.setOnClickListener { loadMore() }
                footViewholder!!.setVisible(R.id.loadmore_default_footer_progressbar, false)
            }
            custom_layout_empty?.visibility = View.GONE
        } else {
            if (dataSet.size > 0) {
                footViewholder!!.setVisible(R.id.layout_empty_default, true)
                footViewholder!!.setText(R.id.loadmore_default_footer_tv, "无更多数据")
                footViewholder!!.setVisible(R.id.loadmore_default_footer_progressbar, false)
                custom_layout_empty?.visibility = View.GONE
            } else {
                footViewholder!!.setVisible(R.id.layout_empty_default, false)
                if (custom_layout_empty == null) {
                    var stub_import = footViewholder!!.itemView.findViewById<ViewStub>(R.id.stub_import)
                    if (stub_import != null) {
                        stub_import.inflate()
                        stub_import = null
                    }
                    custom_layout_empty = footViewholder!!.getView(R.id.custom_layout_empty)
                    if (!TextUtils.isEmpty(emptyText)) {
                        val tv_empty = custom_layout_empty!!.findViewById<TextView>(R.id.tv_empty)
                        tv_empty.text = emptyText
                    }
                    val iv_empty = custom_layout_empty!!.findViewById<ImageView>(R.id.iv_empty)
                    iv_empty.setImageResource(emptyRes)
                }
                custom_layout_empty!!.visibility = View.VISIBLE
            }
        }
    }

    fun addData(t: T) {
        dataSet!!.add(t)
        notifyDataSetChanged()
    }

    interface OnLoadingMore {
        fun onLoadMore()
    }

    protected fun setListener(
        parent: ViewGroup?,
        viewHolder: RViewHolder,
        viewType: Int
    ) {
        viewHolder.convertView.setOnClickListener(View.OnClickListener { v ->
            mOnItemClickListener?.also {
                val position = viewHolder.adapterPosition
                if (TYPE_HEAD == getItemViewType(position)) {
                    return@OnClickListener
                }
                if (TYPE_LOAD_MORE == getItemViewType(position)) {
                    return@OnClickListener
                }
                val p = if (headerView != null) position - 1 else position
                it.onItemClick(v, viewHolder, p)
            }
        })
        viewHolder.convertView.setOnLongClickListener(OnLongClickListener { v ->
            mOnItemClickListener?.also {
                val position = viewHolder.adapterPosition
                if (TYPE_HEAD == getItemViewType(position)) {
                    return@OnLongClickListener false
                }
                if (TYPE_LOAD_MORE == getItemViewType(position)) {
                    return@OnLongClickListener false
                }
                val p = if (headerView != null) position - 1 else position
                return@OnLongClickListener it.onItemLongClick(v, viewHolder, p)
            }
            false
        })
    }

    interface OnItemClickListener {
        fun onItemClick(
            view: View,
            holder: ViewHolder,
            position: Int
        )

        fun onItemLongClick(
            view: View,
            holder: ViewHolder,
            position: Int
        ): Boolean
    }

    fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) {
        mOnItemClickListener = onItemClickListener
    }

    fun addHeaderView(view: View?) {
        headerView = view
    }

    fun setCanLoadMore(canLoadMore: Boolean) {
        this.canLoadMore = canLoadMore
    }

    private var emptyText: String? = null
    private var emptyRes = R.drawable.icon_empty_default
    fun setEmptyContent(txt: String?, res: Int) {
        emptyText = txt
        emptyRes = res
    }

    fun setEmptyRes(emptyRes: Int) {
        this.emptyRes = emptyRes
    }

    fun setEmptyText(emptyText: String?) {
        this.emptyText = emptyText
    }

    companion object {
        const val TYPE_NORMAL = 100
        const val TYPE_HEAD = 101
        const val TYPE_LOAD_MORE = 102
    }

    init {
        //监听recylerview的滑动
        recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                if (dy <= 0) {
                    return
                }
                if (loadMoreComplete && canLoadMore && !isLoading) {
                    var lastVisibleItem = 0
                    val layoutManager = recyclerView.layoutManager
                    if (layoutManager is LinearLayoutManager) {
                        lastVisibleItem = layoutManager.findLastVisibleItemPosition()
                    } else if (layoutManager is GridLayoutManager) {
                        lastVisibleItem = layoutManager.findLastVisibleItemPosition()
                    } else if (layoutManager is StaggeredGridLayoutManager) {
                        if (lastPositions == null) {
                            lastPositions = IntArray(layoutManager.spanCount)
                        }
                        layoutManager.findLastVisibleItemPositions(lastPositions)
                        lastVisibleItem = findMax(lastPositions!!)
                    } else {
                        throw RuntimeException(
                            "Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager"
                        )
                    }
                    if (lastVisibleItem + 1 == itemCount) {
                        loadMore()
                    }
                }
            }
        })
    }
}